인덱스·제약조건·APOC
Neo4j의 성능을 높이고 데이터 무결성을 보장하는 방법, 그리고 강력한 확장 라이브러리 APOC을 다룹니다.
인덱스는 "책의 색인"과 같습니다.
색인이 없으면 원하는 내용을 찾기 위해 책 전체를 넘겨야 하지만,
색인이 있으면 바로 해당 페이지로 갈 수 있죠.
인덱스가 없을 때
MATCH (p:Person {name: "홍길동"}) RETURN p
이 쿼리를 실행하면 Neo4j는 모든 Person 노드를 하나씩 확인합니다.
노드가 100만 개면 100만 번 비교합니다.
인덱스를 생성하면? 거의 즉시 찾아냅니다.
// Person의 name 속성에 인덱스 생성 CREATE INDEX person_name_idx FOR (p:Person) ON (p.name) // 복합 인덱스 (여러 속성) CREATE INDEX person_name_age_idx FOR (p:Person) ON (p.name, p.age)
// 텍스트 검색용 인덱스 — 부분 문자열 검색에 유용 CREATE FULLTEXT INDEX movie_title_ft FOR (m:Movie) ON EACH [m.title] // 사용 CALL db.index.fulltext.queryNodes("movie_title_ft", "인셉") YIELD node RETURN node.title
// 모든 인덱스 목록 조회 SHOW INDEXES // 인덱스 삭제 DROP INDEX person_name_idx
언제 인덱스를 만들어야 하는가?
WHERE에서 자주 검색하는 속성에 만드세요.
특히 name, id, email 같은 식별자 속성에 필수입니다.
단, 인덱스가 너무 많으면 쓰기 성능이 느려질 수 있습니다.
자주 검색하는 속성에만 선별적으로 적용하세요.
제약조건은 "이 규칙을 반드시 지켜라"를 DB에 알려주는 것입니다.
RDB의 UNIQUE, NOT NULL 제약조건과 같은 개념입니다.
// Person의 email은 반드시 고유해야 함 CREATE CONSTRAINT person_email_unique FOR (p:Person) REQUIRE p.email IS UNIQUE // 이후 같은 email로 Person을 만들려고 하면 에러 발생
// Person에는 반드시 name 속성이 있어야 함 CREATE CONSTRAINT person_name_exists FOR (p:Person) REQUIRE p.name IS NOT NULL
// Person은 (name + birthYear) 조합이 고유해야 함 CREATE CONSTRAINT person_key FOR (p:Person) REQUIRE (p.name, p.birthYear) IS NODE KEY
| 제약조건 | 설명 | Community | Enterprise |
|---|---|---|---|
| UNIQUE | 속성 값이 고유해야 함 | 사용 가능 | 사용 가능 |
| IS NOT NULL | 속성이 반드시 존재 | 불가 | 사용 가능 |
| NODE KEY | 복합 키 유일성 + 존재성 | 불가 | 사용 가능 |
제약조건의 부가 효과
UNIQUE 제약조건을 만들면 인덱스도 자동 생성됩니다.
따라서 UNIQUE 제약조건이 있는 속성에는 별도 인덱스를 만들 필요가 없습니다.
MERGE를 사용할 때 UNIQUE 제약조건이 있으면
중복 방지와 성능이 동시에 보장되므로 필수적입니다.
APOC(Awesome Procedures On Cypher)은
Neo4j의 공식 확장 라이브러리입니다.
Cypher만으로는 번거로운 작업을 편하게 해주는 500개 이상의 함수·프로시저를 제공합니다.
설치 방법
Neo4j Desktop: DBMS → Plugins 탭 → APOC 토글 ON
AuraDB: 기본 내장 (별도 설치 불필요, 일부 기능 제한)
데이터 가져오기
CSV, JSON, API 등
외부 데이터를 Neo4j로 적재
apoc.load.csv
apoc.load.json
apoc.load.jdbc
리팩터링
그래프 구조를 변경·정리
라벨 변경, 관계 방향 전환 등
apoc.refactor.rename.label
apoc.refactor.to
apoc.refactor.mergeNodes
유틸리티
텍스트 처리, 날짜 변환,
해시, 컬렉션 조작 등
apoc.text.join
apoc.date.format
apoc.coll.flatten
내보내기
그래프 데이터를
CSV, JSON, GraphML로 추출
apoc.export.csv.all
apoc.export.json.all
apoc.export.graphml.all
가장 자주 사용하는 APOC 패턴들입니다.
// movies.csv: title,year,genre LOAD CSV WITH HEADERS FROM "file:///movies.csv" AS row CREATE (:Movie { title: row.title, year: toInteger(row.year), genre: row.genre })
CALL apoc.load.json("https://api.example.com/movies") YIELD value UNWIND value.movies AS movie MERGE (m:Movie {title: movie.title}) SET m.year = movie.year
// 100만 노드의 속성을 1000개씩 나눠서 업데이트 CALL apoc.periodic.iterate( "MATCH (p:Person) WHERE p.status IS NULL RETURN p", "SET p.status = 'active'", {batchSize: 1000} )
// JSON으로 전체 그래프 내보내기 CALL apoc.export.json.all("graph.json", {}) // CSV로 특정 쿼리 결과 내보내기 CALL apoc.export.csv.query( "MATCH (p:Person)-[:WATCHED]->(m:Movie) RETURN p.name, m.title", "watched.csv", {} )
LOAD CSV vs apoc.load.json
LOAD CSV: Cypher 기본 내장. CSV 파일만 가능. APOC 불필요
apoc.load.json: APOC 필요. JSON, API 호출 가능
CSV 적재만 필요하다면 LOAD CSV만으로 충분합니다.
GDS는 Neo4j의 그래프 분석 알고리즘 라이브러리입니다.
APOC이 "데이터 처리 도구"라면, GDS는 "분석 도구"입니다.
| 알고리즘 | 설명 | 활용 예시 |
|---|---|---|
| PageRank | 노드의 중요도 순위 | 가장 영향력 있는 사람 찾기 |
| Community Detection | 그룹/커뮤니티 탐지 | SNS에서 친구 그룹 발견 |
| Node Similarity | 노드 간 유사도 계산 | 비슷한 취향의 사용자 추천 |
| Shortest Path (가중치) |
비용 기반 최단 경로 Dijkstra, A* 등 |
배달 최적 경로, 네트워크 라우팅 |
| Centrality | 중심성 분석 | 네트워크 허브 노드 탐지 |
GDS는 PART 4(GraphRAG)에서 본격적으로 다룹니다
지금은 "이런 분석이 가능하다" 정도만 알아두세요.
GDS는 지식 그래프 위에서 의미 있는 패턴과 인사이트를 추출하는 도구이며,
GraphRAG에서 LLM과 결합할 때 핵심 역할을 합니다.
이 페이지에서 기억할 것
1. 인덱스
자주 검색하는 속성에 생성 → 조회 성능 대폭 향상. 식별자 속성에 필수
2. 제약조건
UNIQUE → 중복 방지 + 자동 인덱스 생성. MERGE와 함께 사용하면 최적
3. APOC
CSV/JSON 가져오기, 리팩터링, 배치 처리, 내보내기 등 500+개 확장 기능
4. LOAD CSV
Cypher 기본 내장 CSV 적재 도구. 간단한 데이터 가져오기에 APOC 불필요
5. GDS
PageRank, 커뮤니티 탐지 등 그래프 분석 알고리즘. PART 4에서 본격 학습
PART 1 완료!
여기까지 오셨다면 Neo4j와 Cypher의 핵심을 모두 익힌 것입니다.
Ch1: Property Graph 모델 이해
Ch2: Neo4j 환경 구축 (AuraDB / Desktop)
Ch3: Cypher 기본 문법 (CRUD)
Ch4: Cypher 고급 문법 (경로 탐색, 집계, WITH, UNWIND)
Ch5: 인덱스, 제약조건, APOC/GDS